package hotel.callback.oversea.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import hotel.base.oversea.constant.CallbackConstants;
import hotel.base.oversea.constant.CommonConstants;
import hotel.base.oversea.constant.CommonUrlConstants;
import hotel.base.oversea.constant.enums.CommonEnums;
import hotel.base.oversea.constant.enums.MessageEnums;
import hotel.base.oversea.constant.enums.MtHotelEnums;
import hotel.base.oversea.service.impl.BaseServiceImpl;
import hotel.base.oversea.utils.*;
import hotel.base.oversea.vo.meituan.request.goods.MtHotelGoodsStatusDetailStateVo;
import hotel.base.oversea.vo.meituan.request.goods.MtHotelGoodsStatusDetailVo;
import hotel.base.oversea.vo.meituan.request.goods.MtHotelGoodsVo;
import hotel.base.oversea.vo.meituan.response.goods.MtHotelGoodsInventoryVo;
import hotel.base.oversea.vo.meituan.response.goods.MtHotelGoodsPriceBaseDetailVo;
import hotel.base.oversea.vo.meituan.response.goods.MtHotelGoodsPriceBaseVo;
import hotel.base.oversea.vo.meituan.response.goods.MtHotelGoodsPriceVo;
import hotel.callback.oversea.config.service.RedisService;
import hotel.callback.oversea.entity.meituan.MtHotelGoodsPrice;
import hotel.callback.oversea.entity.meituan.MtHotelGoodsPriceChangeLog;
import hotel.callback.oversea.entity.meituan.MtHotelGoodsStatus;
import hotel.callback.oversea.entity.meituan.MtHotelGoodsStatusChangeLog;
import hotel.callback.oversea.mapper.MtHotelGoodsPriceChangeLogMapper;
import hotel.callback.oversea.mapper.MtHotelGoodsPriceMapper;
import hotel.callback.oversea.mapper.MtHotelGoodsStatusChangeLogMapper;
import hotel.callback.oversea.mapper.MtHotelGoodsStatusMapper;
import hotel.callback.oversea.service.MtHotelGoodsService;
import hotel.callback.oversea.task.MeituanSaveApiLogTask;
import hotel.callback.oversea.utils.MtUtils;
import hotel.callback.oversea.vo.meituan.MtHotelGoodsStatusVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class MtHotelGoodsServiceImpl extends BaseServiceImpl implements MtHotelGoodsService {
    @Autowired
    MtHotelGoodsStatusMapper mtHotelGoodsStatusMapper;

    @Autowired
    MtHotelGoodsStatusChangeLogMapper mtHotelGoodsStatusChangeLogMapper;

    @Autowired
    MtHotelGoodsPriceChangeLogMapper mtHotelGoodsPriceChangeLogMapper;

    @Autowired
    MtHotelGoodsPriceMapper mtHotelGoodsPriceMapper;

    @Autowired
    MeituanSaveApiLogTask meituanSaveApiLogTask;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    RedisService redisService;

    @Autowired
    RestTemplate restTemplate;


    /**
     * 根据入住时间和离店时间 查询产品数据
     * 多家酒店，最多查询10家；每家酒店可能存在多个产品；
     * @desc 保存：1、产品信息   2、关联的产品早餐信息
     */
    @Override
    public Result<Object> getMtHotelGoods(List<Long> hotelIds, String checkinDate, String checkoutDate, int goodsType) {
        //业务参数
        String data = "";
        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("hotelIds",hotelIds);
        dataMap.put("checkinDate",checkinDate);
        dataMap.put("checkoutDate",checkoutDate);
        dataMap.put("goodsType",goodsType);
        data = JSON.toJSONString(dataMap);
        //发起请求
        String response = MtUtils.createParamsPost(data, MtHotelEnums.apiMethodEnum.METHOD_HOTEL_GOODS.getMethod(),meituanSaveApiLogTask);
        //处理响应数据
        JSONObject responseJson = JSON.parseObject(response);
        if("0".equals(String.valueOf(responseJson.get("code")))) {
            //上游返回code=0，不管result内容是不是为空，都不能返回为异常，算正常
            String result = responseJson.getString("result");
            if (null != result) {
                MtHotelGoodsVo mtHotelGoodsVo = null;
                try{
                    mtHotelGoodsVo = JSON.parseObject(result,MtHotelGoodsVo.class);
                }catch (Exception e){
                    log.error("//////////////////产品信息解析对象异常："+response);
                    log.error(e.getMessage(),e);
                    return new Result<>("parse error",CommonConstants.REQUEST_ERROR);
                }
                return new Result<>(mtHotelGoodsVo);
            }else{
                log.info("////////////////MTAPIERROR///////////////////酒店产品列表接口数据异常 result is null response="+response);
                return new Result<>(response,CommonConstants.SUCCESS);
            }
        }else{
            log.info("////////////////MTAPIERROR///////////////////酒店产品列表接口数据异常 result code ！=0");
            return new Result<>(responseJson.getString("message"), CommonConstants.REQUEST_ERROR);
        }
    }


    /**
     * 获取产品价格日历不上送酒店id，定时器需要该操作
     *
     * 时间默认上送 开始时间 几天，结束时间明天
     *
     *
     * @param goodsIds
     * @param startDate
     * @param endDate
     * @return
     */
    @Override
    public Result<Object> getMtHotelGoodsPriceNotSave(List<Long> hotelIds, List<Long> goodsIds, String startDate, String endDate) {
        //上游要求：业务参数，hotelId和goodsId传其一，最好hotelId，个数支持最多10
        //上游：注意:hotelIds和goodsIds传一个即可，两个都传优先用hotelIds查询，建议使用hotelIds作为查询条件。
        String data = "";
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("hotelIds", hotelIds);
        dataMap.put("goodsIds", goodsIds);
        dataMap.put("startDate", startDate);
        dataMap.put("endDate", endDate);
        data = JSON.toJSONString(dataMap);
        //发起请求
        String response = MtUtils.createParamsPost(data, MtHotelEnums.apiMethodEnum.METHOD_HOTEL_GOODS_PRICE.getMethod(),meituanSaveApiLogTask);
        //处理响应数据
        JSONObject responseJson = JSON.parseObject(response);
        if ("0".equals(String.valueOf(responseJson.get("code")))) {
            String result = responseJson.getString("result");
            if (!StringUtils.isEmpty(result)) {
                MtHotelGoodsPriceVo mtHotelGoodsPriceVo = null;
                try {
                    mtHotelGoodsPriceVo = JSON.parseObject(result, MtHotelGoodsPriceVo.class);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (null == mtHotelGoodsPriceVo) {
                    log.error("////////////////MTAPIERROR///////////////////酒店产品价格接口数据异常 mtHotelGoodsPriceVo parse vo error:{}，，{}", responseJson, JSON.toJSONString(data));
                    return new Result<>("parse error", CommonConstants.REQUEST_ERROR);
                }
                List<MtHotelGoodsPriceBaseVo> mtHotelGoodsPriceBaseVo = mtHotelGoodsPriceVo.getGoodsPrices();
                if(null == mtHotelGoodsPriceBaseVo){
                    mtHotelGoodsPriceBaseVo = new ArrayList<>();
                }
               /* for (MtHotelGoodsPriceBaseVo base : mtHotelGoodsPriceBaseVo) {
                    List<MtHotelGoodsPriceBaseDetailVo> priceList = base.getPriceModels();
                    if (null != priceList && priceList.size() > 0) {
                        //saveGoodsPriceInfos(priceList,String.valueOf(base.getHotelId()),String.valueOf(base.getGoodsId()));
                        //该方法特殊处理，不做保存更新操作，在外边业务结束后再进行更新价格主表操作
                    } else {
                        //log.error("////////////////MTAPIERROR///////////////////酒店产品价格接口数据异常 goodsList is nul:{}，，{}", responseJson, JSON.toJSONString(data));
                    }
                }*/
                return new Result<>(mtHotelGoodsPriceBaseVo);
            } else {
                log.error("////////////////MTAPIERROR///////////////////酒店产品价格接口数据异常 result is nul：{}，，{}", responseJson, JSON.toJSONString(data));
                return new Result<>("result null", CommonConstants.REQUEST_ERROR);
            }
        } else {
            log.error("////////////////MTAPIERROR///////////////////酒店产品价格接口数据异常：{}，，{}", responseJson, JSON.toJSONString(data));
            return new Result<>(responseJson.getString("message"), CommonConstants.REQUEST_ERROR);
        }
    }

    /**
     * 保存日志，trycatch内容不影响接口流程
     */
    @Override
    public void saveGoodsStatus(List<MtHotelGoodsStatusDetailVo> goodsList,String hotelId){
        List<MtHotelGoodsStatus> goodsEntityList = new ArrayList<>();
        for (MtHotelGoodsStatusDetailVo goods:goodsList){//遍历产品
            List<MtHotelGoodsStatusDetailStateVo> goodsStateDayList = goods.getGoodsStatuses();//某一产品多条某天状态数据
            for (MtHotelGoodsStatusDetailStateVo stateDayVo:goodsStateDayList){
                MtHotelGoodsStatus entity = new MtHotelGoodsStatus();
                String uniKey = hotelId+String.valueOf(goods.getGoodsId())+stateDayVo.getDate().replace("-","");
                entity.setUniKey(uniKey);
                entity.setId(String.valueOf(UUID.randomUUID()));
                entity.setMtHotelId(String.valueOf(hotelId));
                entity.setMtGoodsId(String.valueOf(goods.getGoodsId()));
                entity.setMtGoodsStatus(goods.getStatus());
                entity.setMtCheckDate(stateDayVo.getDate());
                entity.setMtCheckState(stateDayVo.getStatus());
                entity.setState(CommonEnums.STATE_NORMAL.getCode());
                entity.setRemark("");
                entity.setCreateTime(DateUtil.getNowTime());
                entity.setModifyTime(DateUtil.getNowTime());
                goodsEntityList.add(entity);
            }
        }
        try{
             /*//保存前执行删除已存在数据 根据条件  goodsId+checkDate
           int del = mtHotelGoodsStatusMapper.deleteByGoodsIdDay(goodsEntityList);
            if(del != -1){
                mtHotelGoodsStatusMapper.insertList(goodsEntityList);
            }*/
            Integer upInser = mtHotelGoodsStatusMapper.batchUpdateInsert(goodsEntityList);
            if(null != upInser && upInser <= 0){
                log.error("////////////////MTAPIERROR///////////////////酒店产品状态 mtHotelGoodsStatusMapper.saveGoodsStatus 更新插入异常 : {}",upInser);
            }else{
                //log.error("///////////////////////////////////酒店产品状态 mtHotelGoodsStatusMapper.saveGoodsStatus  upInser: {}",upInser);
            }

        }catch (Exception e){
            log.error("saveGoodsStatus 保存失败：goodsEntityList={},hotelId={}", JSON.toJSONString(goodsEntityList),hotelId);
            log.error(e.getMessage(),e);
        }
    }

    /**
     * 保存一个产品的日期价格
     * @param priceList
     * @param hotelId
     * @param goodsId
     */
    @Override
    public void saveGoodsPriceInfos(List<MtHotelGoodsPriceBaseDetailVo> priceList, String hotelId, String goodsId){
        if(null != priceList && priceList.size()>0){
            List<MtHotelGoodsPrice> entityList = new ArrayList<>();
            for (int i = 0; i < priceList.size(); i++) {
                MtHotelGoodsPriceBaseDetailVo goods = priceList.get(i);
                MtHotelGoodsPrice entity = new MtHotelGoodsPrice();
                entity.setId(String.valueOf(UUID.randomUUID()));
                String uniKey = hotelId+goodsId+goods.getDate().replace("-","");
                entity.setUniKey(uniKey);
                entity.setMtHotelId(hotelId);
                entity.setMtSalePrice(goods.getSalePrice());
                entity.setMtGoodsId(goodsId);
                entity.setMtDate(goods.getDate());
                entity.setMtSubPrice(goods.getSubPrice());
                entity.setMtSubRatio(goods.getSubRatio());
                entity.setMtSettlePrice(goods.getSalePrice()-goods.getSubPrice());
                entity.setMtDayType(goods.getDayType());
                entity.setState(CommonEnums.STATE_NORMAL.getCode());
                entity.setRemark("");
                entity.setCreateTime(DateUtil.getNowTime());
                entity.setModifyTime(DateUtil.getNowTime());
                entityList.add(entity);
                //价格改变 更新美团产品相关表数据：增加产品价格变动日志 goods_price_change_log
                /*MtHotelGoodsPriceChangeLog mtHotelGoodsPriceChangeLog = new MtHotelGoodsPriceChangeLog();
                mtHotelGoodsPriceChangeLog.setId(StringUtil.getUUID());
                mtHotelGoodsPriceChangeLog.setMtHotelId(hotelId);
                mtHotelGoodsPriceChangeLog.setMtGoodsId(String.valueOf(goodsId));
                mtHotelGoodsPriceChangeLog.setMtDate(goods.getDate());
                mtHotelGoodsPriceChangeLog.setMtSalePrice(goods.getSalePrice());//最新价格
                mtHotelGoodsPriceChangeLog.setCreateTime(new Date());
                mtHotelGoodsPriceChangeLog.setSource(2);
                //mtHotelGoodsPriceChangeLog.setNowMtSalePrice(price);该字段调整为不保存，不再查出存在的上一个价格产品entity 减少数据库压力；根据库表里的数据就能看出上一次价格是多少
                try {
                    mtHotelGoodsPriceChangeLogMapper.insert(mtHotelGoodsPriceChangeLog);//酒店id+产品id+日期+价格 一般是不会重复，因为有变动的价格才会插入表
                }catch (Exception e){
                    e.printStackTrace();
                }*/
            }
            if(null != entityList && entityList.size()>0){
                Integer upInser = mtHotelGoodsPriceMapper.batchUpdateInsert(entityList);
                if(null != upInser && upInser <= 0){
                    log.error("////////////////MTAPIERROR///////////////////酒店产品价格 mtHotelGoodsInventoryMapper.batchUpdateInsert 更新插入异常 : {}",upInser);
                }else{
                    //log.error("///////////////////////////////////酒店产品库存 mtHotelGoodsInventoryMapper.batchUpdateInsert  upInser: {}",upInser);
                }
            }

        }
    }

    /**
     * 酒店所有产品房态信息(根据酒店时间等查询)
     * 查询2020-05-20 到 2020-05-24
     * 返回多个产品每个产品三条数据，每个产品三条数据的依据是查询时间，2020-05-20 2020-05-21 2020-05-23
     * 包含起始时间，不包含结束时间
     * @param
     * @return
     */
    @Override
    public Result<Object> getMtHotelGoodsStatus(Long hotelId, String checkinDate, String checkoutDate, int goodstype, String source) {
        /*if(StringUtils.isEmpty(checkinDate)
                && StringUtils.isEmpty(checkoutDate)){
            checkinDate = DateUtil.formatDate(new Date(),"yyyy-MM-dd");
            checkoutDate = DateUtil.formatDate(DateUtil.addDay(new Date(),30),"yyyy-MM-dd");
        }*/
        //业务参数
        String data = "";
        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("hotelId",hotelId);
        dataMap.put("checkinDate",checkinDate);
        dataMap.put("checkoutDate",checkoutDate);
        dataMap.put("goodsType",goodstype);
        data = JSON.toJSONString(dataMap);
        //发起请求
        String response = MtUtils.createParamsPost(data, MtHotelEnums.apiMethodEnum.METHOD_HOTEL_GOODS_STATUS.getMethod(),meituanSaveApiLogTask);
        //处理响应数据
        JSONObject responseJson = JSON.parseObject(response);
        if("0".equals(String.valueOf(responseJson.get("code")))) {
            String result = responseJson.getString("result");
            if (!StringUtils.isEmpty(result)) {
                MtHotelGoodsStatusVo mtHotelGoodsStatusVo = null;
                try {
                    mtHotelGoodsStatusVo = JSON.parseObject(result, MtHotelGoodsStatusVo.class);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (null == mtHotelGoodsStatusVo) {
                    log.error("////////////////MTAPIERROR///////////////////酒店产品价格接口数据异常 mtHotelGoodsInventoryVo parse vo error");
                    return new Result<>("parse error", CommonConstants.REQUEST_ERROR);
                }
                List<MtHotelGoodsStatusDetailVo> goodsList = mtHotelGoodsStatusVo.getGoodsStatuses();
                if(null != goodsList && goodsList.size()>0){

                    //保存日志
                    if(null == source){
                        saveGoodsStatus(goodsList,String.valueOf(hotelId));
                    }
                    return new Result<>(mtHotelGoodsStatusVo);

                }else{
                    log.debug("////////////////MTAPIERROR///////////////////酒店产品状态接口数据异常 goodsList is nul:{}",responseJson);
                    return new Result<>(mtHotelGoodsStatusVo);
                }
            }else{
                log.debug("////////////////MTAPIERROR///////////////////酒店产品状态接口数据异常 result is nul",responseJson);
                return new Result<>("result null", CommonConstants.REQUEST_ERROR);
            }
        }else{
            log.error("////////////////MTAPIERROR///////////////////酒店产品状态接口数据异常 {}",responseJson);
            return new Result<>(responseJson.getString("message"), CommonConstants.REQUEST_ERROR);
        }
    }

    /**
     * 用途：第二版-解析房态接口返回数据
     */
    @Override
    public Result<Object> checkMtStatusResultData(String response) {
        //处理响应数据
        JSONObject responseJson = JSON.parseObject(response);
        if("0".equals(String.valueOf(responseJson.get("code")))) {
            String result = responseJson.getString("result");
            if (!StringUtils.isEmpty(result)) {
                MtHotelGoodsStatusVo mtHotelGoodsStatusVo = null;
                try {
                    mtHotelGoodsStatusVo = JSON.parseObject(result, MtHotelGoodsStatusVo.class);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (null == mtHotelGoodsStatusVo) {
                    log.error("////////////////MTAPIERROR///////////////////酒店产品价格接口数据异常 mtHotelGoodsInventoryVo parse vo error");
                    return new Result<>("parse error", CommonConstants.REQUEST_ERROR);
                }
                List<MtHotelGoodsStatusDetailVo> goodsList = mtHotelGoodsStatusVo.getGoodsStatuses();
                if(null != goodsList && goodsList.size()>0){
                    return new Result<>(mtHotelGoodsStatusVo);

                }else{
                    log.debug("////////////////MTAPIERROR///////////////////酒店产品状态接口数据异常 goodsList is nul:{}",responseJson);
                    return new Result<>(mtHotelGoodsStatusVo);
                }
            }else{
                log.debug("////////////////MTAPIERROR///////////////////酒店产品状态接口数据异常 result is nul",responseJson);
                return new Result<>("result null", CommonConstants.REQUEST_ERROR);
            }
        }else{
            log.error("////////////////MTAPIERROR///////////////////酒店产品状态接口数据异常 {}",responseJson);
            return new Result<>(responseJson.getString("message"), CommonConstants.REQUEST_ERROR);
        }
    }

    /**
     * 不包含update数据，只保存日志，外部异步线程update产品房态库表
     * @param hotelId
     * @param goodsId
     * @param date
     * @param priceOrStatus
     * @param source
     * @return
     */
    @Override
    public Boolean checkMtGoodsChange(String today,String nowHourStr,String yestoday,String hotelId, Integer goodsId, String date, Integer priceOrStatus, String source, String apiType, Result rpInfo, String thisTimetampApi) {
        log.info("checkMtGoodsChange酒店={}",hotelId);

        if("room_price".equals(source)){
//            String redisKeyExpiDays = CallbackConstants.REDIS_KEY_CALLBACK_CHANGE_PRICE_HEAD+hotelId+"_"+goodsId+"_"+date;//美团异步推送的缓存酒店+产品+日期
//            Integer has = (Integer)redisTemplate.opsForValue().get(redisKeyExpiDays);
//
//            if(null != redisTemplate.opsForValue().get(CallbackConstants.REDIS_KEY_NOT_CHECK_FOR_PRICE) || null != redisTemplate.opsForValue().get(CallbackConstants.REDIS_KEY_NOT_CHECK_FOR_ALL)){
//                //推全量价格，不比较上一次价格和当前价格是不是相等，直接进入比较合理价------》》》》 这个方法基本不会进来了，现在全量推送是定时器删除产品价格日期缓存
//                Long days = DateUtil.dateDiff(DateUtil.getCurrTime(),"day",date,"yyyy-MM-dd");
//                redisTemplate.opsForValue().set(redisKeyExpiDays,priceOrStatus,Math.abs(days)+2, TimeUnit.DAYS);
//                log.info("353当前价格主动查询接口，不做重复判断，对上架产品所有价格跑直推携程，但需比对合理价");
//                return checkLibrary(apiType,redisKeyExpiDays,has,priceOrStatus,hotelId,goodsId,date,rpInfo);
//            }else{
//                //正常推
//                if(BigDecimal.valueOf(has).compareTo(new BigDecimal(priceOrStatus))!=0){
//                    //上一次价格和当前不一样时判断合理价是否推送
//                    return checkLibrary(apiType,redisKeyExpiDays,has,priceOrStatus,hotelId,goodsId,date,rpInfo);
//                }else{
//                    //一样，异步推送过不再主动推送
//                }
//            }
        }else{//房态变化
            String redisKeyStatusExpiDays = CallbackConstants.REDIS_KEY_CALLBACK_CHANGE_STATUS_HEAD+hotelId+"_"+goodsId+"_"+date;//美团异步推送的缓存酒店+产品+日期
            Integer has = (Integer)redisTemplate.opsForValue().get(redisKeyStatusExpiDays);

            /*if(null != redisTemplate.opsForValue().get(CallbackConstants.REDIS_KEY_NOT_CHECK_FOR_STATUS) || null != redisTemplate.opsForValue().get(CallbackConstants.REDIS_KEY_NOT_CHECK_FOR_ALL)){
                has = null;
                Long days = DateUtil.dateDiff(DateUtil.getCurrTime(),"day",date,"yyyy-MM-dd");
                redisTemplate.opsForValue().set(redisKeyStatusExpiDays,priceOrStatus,Math.abs(days)+2, TimeUnit.DAYS);
                log.info("397当前主动查询房态接口，不做重复判断，对上架产品所有房态跑直推携程");
            }*/

            if(null != has){
                Boolean todo = true;
                String checkBeforeNotNowCanNoPushInHour = (String)redisService.get("swmt_before_not_now_can_no_push_in_hour");//多个时间段逗号隔开，当前设置为"00,01":房态为变化为可预订的不推送，上一次是不可预订最新可预订
                if(null != checkBeforeNotNowCanNoPushInHour){
                    String hourStr = DateUtil.formatDate(new Date(),"HH");
                    if(checkBeforeNotNowCanNoPushInHour.contains(hourStr)){// 00  01  时间段 ，房态为变化为可预订的不推送，上一次是不可预订最新可预订
                        if(BigDecimal.valueOf(has).compareTo(new BigDecimal(priceOrStatus))!=0 && new BigDecimal(priceOrStatus).compareTo(new BigDecimal(1))==0){
                            log.info("指定时间段上一次是不可预订最新可预订checkBeforeNotNowCanNoPushInHour={},房态为变化为可预订的不推送goodsid={},priceOrStatus={},has={}",checkBeforeNotNowCanNoPushInHour,goodsId,priceOrStatus,has);
                            todo =false;
                        }
                    }
                }

                if(todo && BigDecimal.valueOf(has).compareTo(new BigDecimal(priceOrStatus))!=0){
                    //异步缓存不一样，主动这边没推送过，处理推送并更新缓存
                    redisTemplate.opsForValue().set("compare_time_for_mt_callback_status_"+hotelId+"_"+goodsId+"_"+date,DateUtil.getCurrTime(),40,TimeUnit.MINUTES);
                    return dealStatus(redisKeyStatusExpiDays,priceOrStatus,hotelId,goodsId,date,apiType,thisTimetampApi);
                }else{
                    //一样，异步推送过不再主动推送
                }
            }else{
                Boolean todo = true;
                String checkBeforeNotNowCanNoPushInHour = (String)redisService.get("swmt_before_not_now_can_no_push_in_hour");//多个时间段逗号隔开，当前设置为"00,01":在这段时间主动查询的价格不推送降价和上一次价格相比（当前暂时不对异步做处理，00,01这两个时间点异步是关闭的）
                if(null != checkBeforeNotNowCanNoPushInHour){
                    String hourStr = DateUtil.formatDate(new Date(),"HH");
                    if(checkBeforeNotNowCanNoPushInHour.contains(hourStr)){// 00  01  时间段 ，房态为变化为可预订的不推送，上一次是不可预订最新可预订
                        if(new BigDecimal(priceOrStatus).compareTo(new BigDecimal(1))==0){
                            log.info("has为空，指定时间段checkBeforeNotNowCanNoPushInHour={},房态为可预订的不推送goodsid={},priceOrStatus={},has={}",checkBeforeNotNowCanNoPushInHour,goodsId,priceOrStatus,has);
                            todo =false;
                        }
                    }
                }

                if(todo){
                    //需push 返回true
                    redisTemplate.opsForValue().set("compare_time_for_mt_callback_status_"+hotelId+"_"+goodsId+"_"+date,DateUtil.getCurrTime(),40,TimeUnit.MINUTES);
                    return dealStatus(redisKeyStatusExpiDays,priceOrStatus,hotelId,goodsId,date,apiType,thisTimetampApi);
                }

            }
        }

        return false;
    }

//    /**
//     * 用途: 主动查询（美团接口不包含endDate 包含startDate）
//     * @return
//     */
//    @Override
//    public Integer getDaysCommonBaseSet() {
//        Integer returnDays;
//        String daysCom = (String)redisService.get(CallbackConstants.SWMT_PRICE_STATUS_DAYS);
//        if(ObjectUtils.isEmpty(daysCom)){
//            Result result = RestTemplateUtils.get(CommonUrlConstants.ADMIN_HOST+"/sysCommonBase/value/"+CallbackConstants.SWMT_PRICE_STATUS_DAYS,null,restTemplate);
//            if(result.getCode() == CommonConstants.SUCCESS && !ObjectUtils.isEmpty(result.getData())){
//                daysCom = (String)result.getData();
//                redisService.set(CallbackConstants.SWMT_PRICE_STATUS_DAYS,daysCom);
//                returnDays = Integer.valueOf(daysCom);
//            }else{
//                SendUtils.dingMsgNotLog("获取基础配置days异常请排查",DateUtil.getCurrTime()+" 当前设置默认值价格房态查询3天 result="+GsonUtils.GsonString(result), MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode(),restTemplate);
//                returnDays = 3;//有异常默认3天并推送钉钉
//            }
//        }else{
//            returnDays = Integer.valueOf(daysCom);
//        }
//
//        return returnDays;
//
//    }

    /**
     * 获取上架date日期map json串
     * 用途：callback异步作为时间判断
     * @return
     */
    @Override
    public Map<String, String> findUpDateMap(Integer thisHotelId,String nowHourStr) {
        Result<Object> daysResult = this.getDaysCommonBaseSetForCallbackRole(thisHotelId);
        Map<String,String> disDaysMap = null;
        String redisKeyMap = "swmt_callback_pass_date_map_vip";
        if(!daysResult.getMsg().equals("VIP")){
            redisKeyMap = "swmt_callback_pass_date_map_normal";
        }
        String endDate = null;
        String disDaysMapStr = (String)redisService.get(redisKeyMap);
        if(ObjectUtils.isEmpty(disDaysMapStr)){
            Integer cbDays = (Integer)daysResult.getData();
            String queryStartTime = DateUtil.formatDate(new Date(),"yyyy-MM-dd");
            if(Integer.valueOf(nowHourStr)<6){
                queryStartTime = DateUtil.getFrontDay(queryStartTime,-1);//查询昨天
            }
            String  queryEndDate = DateUtil.formatDate(DateUtil.addDay(queryStartTime,cbDays),"yyyy-MM-dd");
            /*if(null != redisService.get("query_status_time_days_endDate")){
                queryEndDate = (String)redisService.get("query_status_time_days_endDate");
            }*/
            disDaysMap = DateUtil.getTwoDaysDayIndex(queryStartTime,queryEndDate);
            redisService.setUnit(redisKeyMap, GsonUtils.GsonString(disDaysMap),30L,TimeUnit.MINUTES);
            log.info("callback过滤结束时间：{}",endDate);
        }else{
            disDaysMap = GsonUtils.GsonToMaps(disDaysMapStr);
        }
        return disDaysMap;

    }


//    /**
//     * 用途: 美团异步通道（days要减一）
//     * @return
//     */
//    @Override
//    public Integer getDaysCommonBaseSetForCallback(Integer hotelId) {
//        Boolean isVip = redisService.isMember(CommonConstants.SWITCH_SALE_HOTEL_VIP,hotelId);
//        if(isVip){//优势酒店
//            log.info("is Vip getDaysCommonBaseSetForCallback hotelId={}",hotelId);
//            return getDaysCommonBaseSetForVip()-1;
//        }else{//普通酒店
//            log.info("is Normal getDaysCommonBaseSetForCallback hotelId={}",hotelId);
//            return getDaysCommonBaseSetForNormal()-1;
//        }
//    }

    /**
     * 用途: 美团异步通道（days要减一）,返回具体所属优势还是普通；当前为异步使用，需-1
     * @return
     */
    @Override
    public Result<Object> getDaysCommonBaseSetForCallbackRole(Integer hotelId) {
        try {
            Boolean isVip = redisService.isMember(CommonConstants.SWITCH_SALE_HOTEL_VIP,hotelId);
            if(isVip){//优势酒店
                String callbackDaysVip = (String)redisService.get(CallbackConstants.SWMT_VIP_HOTELS_PRICE_STATUS_FOR_CALLBACK);//-1
                if(ObjectUtils.isEmpty(callbackDaysVip)){
                    callbackDaysVip = String.valueOf(getDaysCommonBaseSetForVip()-1);
                    redisService.set(CallbackConstants.SWMT_VIP_HOTELS_PRICE_STATUS_FOR_CALLBACK,callbackDaysVip);
                }
                log.info("is Vip getDaysCommonBaseSetForCallback hotelId={}",hotelId);
                return new Result<>(Integer.valueOf(callbackDaysVip), "VIP",CommonConstants.SUCCESS);
            }else{//普通酒店
                Boolean isNormal = redisService.isMember(CommonConstants.SWITCH_SALE_HOTEL_NORMAL,hotelId);
                if(isNormal){
                    log.info("is Normal getDaysCommonBaseSetForCallback hotelId={}",hotelId);
                }else{
                    log.info("error not find getDaysCommonBaseSetForCallback hotelId={}",hotelId);
                }
                String callbackDaysNormal = (String)redisService.get(CallbackConstants.SWMT_NORMAL_HOTELS_PRICE_STATUS_FOR_CALLBACK);//-1
                if(ObjectUtils.isEmpty(callbackDaysNormal)){
                    callbackDaysNormal = String.valueOf(getDaysCommonBaseSetForNormal()-1);
                    redisService.set(CallbackConstants.SWMT_NORMAL_HOTELS_PRICE_STATUS_FOR_CALLBACK,callbackDaysNormal);
                }
                return new Result<>(Integer.valueOf(callbackDaysNormal), "NORMAL",CommonConstants.SUCCESS);
            }
        }catch (Exception e){
            log.info("getDaysCommonBaseSetForCallbackRole 异常默认返回3-1：",e.getMessage());
            e.printStackTrace();
            log.info("is error getDaysCommonBaseSetForCallback hotelId={}",hotelId);
            return new Result<>(3-1, "NORMAL",CommonConstants.SUCCESS);
        }

    }

    /**
     * 上架天数：普通酒店：3天
     * @return
     */
    @Override
    public Integer getDaysCommonBaseSetForNormal() {
        Integer returnDays;
        String daysCom = (String)redisService.get(CallbackConstants.SWMT_NORMAL_HOTELS_PRICE_STATUS_DAYS);
        if(ObjectUtils.isEmpty(daysCom)){
            Result result = RestTemplateUtils.get(CommonUrlConstants.ADMIN_HOST+"/sysCommonBase/value/"+CallbackConstants.SWMT_NORMAL_HOTELS_PRICE_STATUS_DAYS,null,restTemplate);
            if(result.getCode() == CommonConstants.SUCCESS && !ObjectUtils.isEmpty(result.getData())){
                daysCom = (String)result.getData();
                redisService.set(CallbackConstants.SWMT_NORMAL_HOTELS_PRICE_STATUS_DAYS,daysCom);
                returnDays = Integer.valueOf(daysCom);
            }else{
                SendUtils.dingMsgNotLog("callback getDaysCommonBaseSetForNormal获取基础配置days异常请排查",DateUtil.getCurrTime()+" 当前设置默认值价格房态查询3天 result="+GsonUtils.GsonString(result), MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode(),restTemplate);
                returnDays = 3;//有异常默认3天并推送钉钉
            }
        }else{
            returnDays = Integer.valueOf(daysCom);
        }

        return returnDays;

    }

    /**
     * 上架天数：优势酒店：5天
     * @return
     */
    @Override
    public Integer getDaysCommonBaseSetForVip() {
        Integer returnDays;
        String daysCom = (String)redisService.get(CallbackConstants.SWMT_VIP_HOTELS_PRICE_STATUS_DAYS);
        if(ObjectUtils.isEmpty(daysCom)){
            Result result = RestTemplateUtils.get(CommonUrlConstants.ADMIN_HOST+"/sysCommonBase/value/"+CallbackConstants.SWMT_VIP_HOTELS_PRICE_STATUS_DAYS,null,restTemplate);
            if(result.getCode() == CommonConstants.SUCCESS && !ObjectUtils.isEmpty(result.getData())){
                daysCom = (String)result.getData();
                redisService.set(CallbackConstants.SWMT_VIP_HOTELS_PRICE_STATUS_DAYS,daysCom);
                returnDays = Integer.valueOf(daysCom);
            }else{
                SendUtils.dingMsgNotLog("callback getDaysCommonBaseSetForVip获取基础配置days异常请排查",DateUtil.getCurrTime()+" 当前设置默认值价格房态查询5天 result="+GsonUtils.GsonString(result), MessageEnums.genre.GOODS_STATUS_AND_PRICE.getCode(),restTemplate);
                returnDays = 5;//有异常默认5天并推送钉钉
            }
        }else{
            returnDays = Integer.valueOf(daysCom);
        }

        return returnDays;

    }
    @Override
    public Boolean dealPrice(Long days,Integer tj,Integer pushSalePrice,Integer subPrice,String redisKeyExpiDaysQueryPrice, Integer apiSalePrice,
                             String hotelId, Integer goodsId, String date, String apiType,Integer changeToLibraryPrice,Integer has,Integer changeToLibraryPriceBefore,String thisTimestampApi,Integer fromJob) {
        redisTemplate.opsForValue().set(redisKeyExpiDaysQueryPrice,pushSalePrice,Math.abs(days)+2, TimeUnit.DAYS);//！！当推送的是标准价（售卖价小于标准价），当前set到缓存的不set标准价，不然每一次查询到最新价和缓存价不同都会进行推送死循环

        /*if(null !=redisService.get("swmt_change_notice_price_sub_hhb")){//20210406 qyy 每个月月初 佣金会降低到8.5%，经过1-2天订单有1000以上
            String hhbSub = (String)redisService.get("swmt_change_notice_price_sub_hhb");
            //   subPrice/priceOrStatus = 0.08
            //BigDecimal.valueOf(0.075).compareTo()
            Integer newSubPrice = BigDecimal.valueOf(priceOrStatus).multiply(BigDecimal.valueOf(Double.valueOf(hhbSub))).intValue();
            subPrice = newSubPrice;
        }*/
        //设置佣金缓存 携程需要
        redisTemplate.opsForValue().set(CallbackConstants.REDIS_KEY_CALLBACK_SUB_PRICE_HEAD+hotelId+"_"+goodsId+"_"+date,pushSalePrice+"_"+subPrice,Math.abs(days)+2, TimeUnit.DAYS);

        //价格改变 更新美团产品相关表数据：增加产品价格变动日志 goods_price_change_log
        MtHotelGoodsPriceChangeLog mtHotelGoodsPriceChangeLog = new MtHotelGoodsPriceChangeLog();
        mtHotelGoodsPriceChangeLog.setId(StringUtil.getUUID());
        mtHotelGoodsPriceChangeLog.setMtHotelId(hotelId);
        mtHotelGoodsPriceChangeLog.setMtGoodsId(String.valueOf(goodsId));
        mtHotelGoodsPriceChangeLog.setMtDate(date);
        mtHotelGoodsPriceChangeLog.setMtSalePrice(apiSalePrice);//最新价格
        mtHotelGoodsPriceChangeLog.setCreateTime(new Date());
        mtHotelGoodsPriceChangeLog.setRemark(thisTimestampApi+"_"+pushSalePrice+"_"+apiSalePrice+"_"+has+"="+changeToLibraryPrice+"_"+changeToLibraryPriceBefore+"_"+tj);
        if(!ObjectUtils.isEmpty(fromJob)){
            mtHotelGoodsPriceChangeLog.setSource(fromJob);
        }else{
            if(null == changeToLibraryPrice){
                mtHotelGoodsPriceChangeLog.setSource(1);
            }else{
                log.info("有标准价，但是has又是null 更新为标准价标识不为空goodsId={},changeToLibraryPrice={},remark={},changeToLibraryPriceBefore={},tj={},pushSalePrice={}",goodsId,changeToLibraryPrice,apiSalePrice+"_"+changeToLibraryPrice,changeToLibraryPriceBefore,tj,pushSalePrice);
                mtHotelGoodsPriceChangeLog.setSource(4);
            }
        }
        mtHotelGoodsPriceChangeLog.setType(apiType);
        //mtHotelGoodsPriceChangeLog.setNowMtSalePrice(price);该字段调整为不保存，不再查出存在的上一个价格产品entity 减少数据库压力；根据库表里的数据就能看出上一次价格是多少
        try {
            mtHotelGoodsPriceChangeLogMapper.insert(mtHotelGoodsPriceChangeLog);//酒店id+产品id+日期+价格 一般是不会重复，因为有变动的价格才会插入表
        }catch (Exception e){
            log.error("价格日志保存失败goodsId={}changeToLibraryPrice={},remark={},changeToLibraryPriceBefore={},m={}",goodsId,changeToLibraryPrice,apiSalePrice+"_"+changeToLibraryPrice,changeToLibraryPriceBefore,e.getMessage());
            e.printStackTrace();
        }
        return true;
    }
    private boolean dealStatus(String redisKeyExpiDaysQueryStatus,Integer priceOrStatus,String hotelId,Integer goodsId,String date,String apiType,String thisTimetampApi){
        //日期房态发生变化 需要更新
        Long days = DateUtil.dateDiff(DateUtil.getCurrTime(),"day",date,"yyyy-MM-dd");
        redisTemplate.opsForValue().set(redisKeyExpiDaysQueryStatus,priceOrStatus,Math.abs(days)+2,TimeUnit.DAYS);
        //价格改变 更新美团产品相关表数据：增加产品房态变动日志
        MtHotelGoodsStatusChangeLog mtHotelGoodsStatusChangeLog = new MtHotelGoodsStatusChangeLog();
        mtHotelGoodsStatusChangeLog.setId(StringUtil.getUUID());
        mtHotelGoodsStatusChangeLog.setMtHotelId(hotelId);
        mtHotelGoodsStatusChangeLog.setMtGoodsId(String.valueOf(goodsId));
        mtHotelGoodsStatusChangeLog.setMtDate(date);
        mtHotelGoodsStatusChangeLog.setStatus(priceOrStatus);
        mtHotelGoodsStatusChangeLog.setType(apiType);
        mtHotelGoodsStatusChangeLog.setRemark(thisTimetampApi);
        mtHotelGoodsStatusChangeLog.setCreateTime(new Date());
        log.info("meituan_push_hhb_change_status_data_hotel_goodsId={},{}",hotelId+"_"+goodsId, JSON.toJSONString(mtHotelGoodsStatusChangeLog));
        try {
            mtHotelGoodsStatusChangeLogMapper.insert(mtHotelGoodsStatusChangeLog);
        }catch (Exception e){
            e.printStackTrace();
        }
        return true;
    }

    /**
     * 请求获取酒店产品价格并保存
     *
     * 无论上送时间 只返回一个对象 显示有无库存
     * @param
     * @return
     */
    @Override
    public Result<Object> getMtHotelGoodsInventoryNotSaveLog(int goodsId, int roomId, String startDate, String endDate) {
        //业务参数
        String data = "";
        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("goodsId",goodsId);
        dataMap.put("roomId",roomId);
        dataMap.put("startDate",startDate);
        dataMap.put("endDate",endDate);
        data = JSON.toJSONString(dataMap);
        //发起请求
        String response = MtUtils.createParamsPost(data, MtHotelEnums.apiMethodEnum.METHOD_HOTEL_GOODS_INVENTORY.getMethod(),meituanSaveApiLogTask);
        //处理响应数据
        JSONObject responseJson = JSON.parseObject(response);
        if("0".equals(String.valueOf(responseJson.get("code")))) {
            String inventory = responseJson.getJSONObject("result").getString("goodsInventory");
            if (null != inventory) {
                MtHotelGoodsInventoryVo mtHotelGoodsInventoryVo = null;
                try {
                    mtHotelGoodsInventoryVo = JSON.parseObject(inventory, MtHotelGoodsInventoryVo.class);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (null == mtHotelGoodsInventoryVo) {
                    log.error("////////////////MTAPIERROR///////////////////酒店产品库存数据异常 mtHotelGoodsInventoryVo parse vo error");
                    return new Result<>("parse error", CommonConstants.PARSE_ERROR);
                }

                return new Result<>(mtHotelGoodsInventoryVo);

            }else{
                log.error("////////////////MTAPIERROR///////////////////酒店产品库存接口数据异常 inventory is null");
                return new Result<>("inventory null", CommonConstants.REQUEST_ERROR);
            }
        }else{
            log.error("////////////////MTAPIERROR///////////////////酒店产品库存接口数据异常 {}",responseJson);
            return new Result<>(responseJson.getString("message"), CommonConstants.REQUEST_ERROR);
        }
    }

}
